package com.ktjy.auth.service.impl;

import com.ktjy.auth.base.SecurityUser;
import com.ktjy.auth.service.AuthService;
import com.ktjy.auth.util.JWTAuth;
import jakarta.annotation.Resource;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.Objects;

/**
 * 认证服务实现类
 *
 * @author LILIBO
 * @since 2023-02-23
 */
@Service
public class AuthServiceImpl implements AuthService {

    @Resource
    private AuthenticationManager authenticationManager;

    /**
     * 登录（获取Token）
     *
     * @param username 用户名
     * @param password 密码
     * @return
     */
    @Override
    public String login(String username, String password) {
        if (username.isEmpty() || password.isEmpty()) {
            throw new RuntimeException("提交的验证数据有误");
        }
        // 由SpringSecurity框架进行账号密码验证
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(username, password);
        Authentication authenticate = authenticationManager.authenticate(authenticationToken);
        if (Objects.isNull(authenticate)) {
            throw new RuntimeException("用户名或密码错误");
        }
        // 验证通过，获取认证主体
        SecurityUser securityUser = (SecurityUser) authenticate.getPrincipal();
        // 通过UserDetails中保存的业务用户对象获取ID生成Token，同时将登录用户对象数据存储到Redis，以备其他接口调用时，通过Token中的UID获取并验证
        return JWTAuth.generateJWT(securityUser);
    }

    /**
     * 验证（验证Token合法性）
     *
     * @param token 令牌
     * @return
     */
    @Override
    public boolean verify(String token) {
        boolean verify; // 验证结果
        try {
            verify = JWTAuth.verifyJWT(token);
        } catch (Exception e) {
            verify = false; // 发生异常，判定为验证失败
        }
        return verify;
    }

    /**
     * 退出登录（移除Redis中的对象信息）
     *
     * @param userId 用户ID
     * @return
     */
    @Override
    public boolean logout(Long userId) {
        return JWTAuth.removeJWT(userId);
    }

}
